+++ /dev/null
-Description: Avoid installing dev-dependencies
-Author: Ximin Luo <infinity0@pwned.gg>
-Applied-Upstream: https://github.com/rust-lang/cargo/pull/5012
-Applied-Upstream: https://github.com/rust-lang/cargo/pull/5186
---- a/src/bin/build.rs
-+++ b/src/bin/build.rs
-@@ -98,7 +98,10 @@
- &options.flag_z)?;
-
- let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
-- let ws = Workspace::new(&root, config)?;
-+ let mut ws = Workspace::new(&root, config)?;
-+ if config.cli_unstable().avoid_dev_deps {
-+ ws.set_require_optional_deps(false);
-+ }
-
- let spec = Packages::from_flags(options.flag_all,
- &options.flag_exclude,
---- a/src/cargo/core/features.rs
-+++ b/src/cargo/core/features.rs
-@@ -272,6 +272,7 @@
- pub unstable_options: bool,
- pub offline: bool,
- pub no_index_update: bool,
-+ pub avoid_dev_deps: bool,
- }
-
- impl CliUnstable {
-@@ -304,6 +305,7 @@
- "unstable-options" => self.unstable_options = true,
- "offline" => self.offline = true,
- "no-index-update" => self.no_index_update = true,
-+ "avoid-dev-deps" => self.avoid_dev_deps = true,
- _ => bail!("unknown `-Z` flag specified: {}", k),
- }
-
---- a/src/cargo/core/resolver/mod.rs
-+++ b/src/cargo/core/resolver/mod.rs
-@@ -96,14 +96,26 @@
-
- #[derive(Clone, Copy)]
- pub enum Method<'a> {
-- Everything,
-+ Everything, // equivalent to Required { dev_deps: true, all_features: true, .. }
- Required {
- dev_deps: bool,
- features: &'a [String],
-+ all_features: bool,
- uses_default_features: bool,
- },
- }
-
-+impl<'r> Method<'r> {
-+ pub fn split_features(features: &[String]) -> Vec<String> {
-+ features.iter()
-+ .flat_map(|s| s.split_whitespace())
-+ .flat_map(|s| s.split(','))
-+ .filter(|s| !s.is_empty())
-+ .map(|s| s.to_string())
-+ .collect::<Vec<String>>()
-+ }
-+}
-+
- // Information about the dependencies for a crate, a tuple of:
- //
- // (dependency info, candidates, features activated)
-@@ -711,6 +723,7 @@
- let method = Method::Required {
- dev_deps: false,
- features: &features,
-+ all_features: false,
- uses_default_features: dep.uses_default_features(),
- };
- trace!("{}[{}]>{} trying {}", parent.name(), cur, dep.name(),
-@@ -1000,7 +1013,8 @@
- -> CargoResult<Requirements<'a>> {
- let mut reqs = Requirements::new(s);
- match *method {
-- Method::Everything => {
-+ Method::Everything |
-+ Method::Required { all_features: true, .. } => {
- for key in s.features().keys() {
- reqs.require_feature(key)?;
- }
-@@ -1046,10 +1060,11 @@
- }
- debug!("checking if {} is already activated", summary.package_id());
- let (features, use_default) = match *method {
-+ Method::Everything |
-+ Method::Required { all_features: true, .. } => return false,
- Method::Required { features, uses_default_features, .. } => {
- (features, uses_default_features)
- }
-- Method::Everything => return false,
- };
-
- let has_default_feature = summary.features().contains_key("default");
---- a/src/cargo/core/workspace.rs
-+++ b/src/cargo/core/workspace.rs
-@@ -64,7 +64,8 @@
-
- // True if this workspace should enforce optional dependencies even when
- // not needed; false if this workspace should only enforce dependencies
-- // needed by the current configuration (such as in cargo install).
-+ // needed by the current configuration (such as in cargo install). In some
-+ // cases `false` also results in the non-enforcement of dev-dependencies.
- require_optional_deps: bool,
- }
-
-@@ -300,6 +301,11 @@
- self.require_optional_deps
- }
-
-+ pub fn set_require_optional_deps<'a>(&'a mut self, require_optional_deps: bool) -> &mut Workspace<'cfg> {
-+ self.require_optional_deps = require_optional_deps;
-+ self
-+ }
-+
- /// Finds the root of a workspace for the crate whose manifest is located
- /// at `manifest_path`.
- ///
---- a/src/cargo/ops/cargo_compile.rs
-+++ b/src/cargo/ops/cargo_compile.rs
-@@ -29,7 +29,7 @@
-
- use core::{Source, Package, Target};
- use core::{Profile, TargetKind, Profiles, Workspace, PackageId, PackageIdSpec};
--use core::resolver::Resolve;
-+use core::resolver::{Resolve, Method};
- use ops::{self, BuildOutput, Executor, DefaultExecutor};
- use util::config::Config;
- use util::{CargoResult, profile};
-@@ -226,12 +226,18 @@
- let profiles = ws.profiles();
-
- let specs = spec.into_package_id_specs(ws)?;
-- let resolve = ops::resolve_ws_precisely(ws,
-- source,
-- features,
-- all_features,
-- no_default_features,
-- &specs)?;
-+ let features = Method::split_features(features);
-+ let method = Method::Required {
-+ dev_deps: ws.require_optional_deps() || filter.need_dev_deps(mode),
-+ features: &features,
-+ all_features,
-+ uses_default_features: !no_default_features,
-+ };
-+ let resolve = ops::resolve_ws_with_method(ws,
-+ source,
-+ method,
-+ &specs,
-+ )?;
- let (packages, resolve_with_overrides) = resolve;
-
- if specs.is_empty() {
-@@ -413,6 +419,22 @@
- }
- }
-
-+ pub fn need_dev_deps(&self, mode: CompileMode) -> bool {
-+ match mode {
-+ CompileMode::Test | CompileMode::Doctest | CompileMode::Bench => true,
-+ CompileMode::Build | CompileMode::Doc { .. } | CompileMode::Check { .. } => match *self
-+ {
-+ CompileFilter::Default { .. } => false,
-+ CompileFilter::Only {
-+ ref examples,
-+ ref tests,
-+ ref benches,
-+ ..
-+ } => examples.is_specific() || tests.is_specific() || benches.is_specific(),
-+ },
-+ }
-+ }
-+
- pub fn matches(&self, target: &Target) -> bool {
- match *self {
- CompileFilter::Default { .. } => true,
---- a/src/cargo/ops/cargo_install.rs
-+++ b/src/cargo/ops/cargo_install.rs
-@@ -175,7 +175,11 @@
-
- let ws = match overidden_target_dir {
- Some(dir) => Workspace::ephemeral(pkg, config, Some(dir), false)?,
-- None => Workspace::new(pkg.manifest_path(), config)?,
-+ None => {
-+ let mut ws = Workspace::new(pkg.manifest_path(), config)?;
-+ ws.set_require_optional_deps(false);
-+ ws
-+ }
- };
- let pkg = ws.current()?;
-
---- a/src/cargo/ops/mod.rs
-+++ b/src/cargo/ops/mod.rs
-@@ -22,7 +22,7 @@
- pub use self::registry::configure_http_handle;
- pub use self::cargo_fetch::fetch;
- pub use self::cargo_pkgid::pkgid;
--pub use self::resolve::{resolve_ws, resolve_ws_precisely, resolve_with_previous};
-+pub use self::resolve::{resolve_ws, resolve_ws_precisely, resolve_ws_with_method, resolve_with_previous};
- pub use self::cargo_output_metadata::{output_metadata, OutputMetadataOptions, ExportInfo};
-
- mod cargo_clean;
---- a/src/cargo/ops/resolve.rs
-+++ b/src/cargo/ops/resolve.rs
-@@ -29,13 +29,25 @@
- no_default_features: bool,
- specs: &[PackageIdSpec])
- -> CargoResult<(PackageSet<'a>, Resolve)> {
-- let features = features.iter()
-- .flat_map(|s| s.split_whitespace())
-- .flat_map(|s| s.split(','))
-- .filter(|s| !s.is_empty())
-- .map(|s| s.to_string())
-- .collect::<Vec<String>>();
-+ let features = Method::split_features(features);
-+ let method = if all_features {
-+ Method::Everything
-+ } else {
-+ Method::Required {
-+ dev_deps: true,
-+ features: &features,
-+ all_features: false,
-+ uses_default_features: !no_default_features,
-+ }
-+ };
-+ resolve_ws_with_method(ws, source, method, specs)
-+}
-
-+pub fn resolve_ws_with_method<'a>(ws: &Workspace<'a>,
-+ source: Option<Box<Source + 'a>>,
-+ method: Method,
-+ specs: &[PackageIdSpec])
-+ -> CargoResult<(PackageSet<'a>, Resolve)> {
- let mut registry = PackageRegistry::new(ws.config())?;
- if let Some(source) = source {
- registry.add_preloaded(source);
-@@ -68,16 +80,6 @@
- None
- };
-
-- let method = if all_features {
-- Method::Everything
-- } else {
-- Method::Required {
-- dev_deps: true, // TODO: remove this option?
-- features: &features,
-- uses_default_features: !no_default_features,
-- }
-- };
--
- let resolved_with_overrides =
- ops::resolve_with_previous(&mut registry,
- ws,
-@@ -236,6 +238,7 @@
- let base = Method::Required {
- dev_deps: dev_deps,
- features: &[],
-+ all_features: false,
- uses_default_features: true,
- };
- let member_id = member.package_id();